package com.zyb.warehouse.controller;

import com.google.code.kaptcha.Producer;
import com.zyb.warehouse.common.Result;
import com.zyb.warehouse.entity.Auth;
import com.zyb.warehouse.entity.CurrentUser;
import com.zyb.warehouse.entity.LoginUser;
import com.zyb.warehouse.entity.User;
import com.zyb.warehouse.service.AuthService;
import com.zyb.warehouse.service.LoginService;
import com.zyb.warehouse.utils.DigestUtil;
import com.zyb.warehouse.utils.TokenUtils;
import com.zyb.warehouse.utils.WarehouseConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Description:登录相关控制层
 */
@RestController
public class LoginController {

    //根据byName进行注入,用来生成验证码图片
    @Resource(name = "captchaProducer")
    private Producer producer;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private LoginService loginService;
    @Autowired
    private AuthService authService;
    @Autowired
    private TokenUtils tokenUtils;

    /**
     * 生成验证码图片的方法
     *
     * @param response
     */
    @RequestMapping("/captcha/captchaImage")
    public void captcha(HttpServletResponse response) {
        ServletOutputStream out = null;
        try {
            //验证码文本
            String text = producer.createText();
            //根据test文本生成验证码图片--BufferedImage代表生成的验证码图片在内存中
            BufferedImage image = producer.createImage(text);
            //将验证码文本作为键存到redis中
            redisTemplate.opsForValue().set(text, "", 60 * 5, TimeUnit.SECONDS);
            //将验证码响应给前端
            response.setContentType("image/jpeg");
            //获取输出流
            out = response.getOutputStream();
            ImageIO.write(image, "jpg", out);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 用户登录
     *
     * @param loginUser
     * @return
     */
    @RequestMapping("/login")
    public Result login(@RequestBody LoginUser loginUser) {
        //获取用户输入的验证码
        String code = loginUser.getVerificationCode();
        //判断验证码是否过期
        if (!redisTemplate.hasKey(code)) {
            return Result.err(Result.CODE_ERR_BUSINESS, "验证码已过期");
        }
        User user = loginService.queryUserByCode(loginUser.getUserCode());
        if (user != null) {//用户存在
            if (user.getUserState().equals(WarehouseConstants.USER_STATE_PASS)) {//用户已审核
                String userPwd = DigestUtil.hmacSign(loginUser.getUserPwd());
                if (userPwd.equals(user.getUserPwd())) {//密码正确
                    //生成jwtToken
                    CurrentUser currentUser = new CurrentUser(
                            user.getUserId(), user.getUserCode(), user.getUserName());
                    String token = tokenUtils.loginSign(currentUser, userPwd);
                    return Result.ok("登录成功", token);
                } else {
                    return Result.err(Result.CODE_ERR_BUSINESS, "密码错误");
                }
            } else {
                return Result.err(Result.CODE_ERR_BUSINESS, "用户未审核");
            }
        } else {
            return Result.err(Result.CODE_ERR_BUSINESS, "用户不存在");
        }
    }

    /**
     * 获取登录用户的信息
     *
     * @param token
     * @return
     */
    @GetMapping("/curr-user")
    public Result getLoginUserInfo(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token) {
        CurrentUser currentUser = tokenUtils.getCurrentUser(token);
        return Result.ok(currentUser);
    }

    /**
     * 加载用户权限菜单树
     *
     * @param token
     * @return
     */
    @GetMapping("/user/auth-list")
    public Result loadAuthTree(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token) {
        //从前端归还的token中解析出当前登录用户的信息
        CurrentUser currentUser = tokenUtils.getCurrentUser(token);
        int userId = currentUser.getUserId();
        //根据用户id查询用户权限(菜单)树
        List<Auth> userAuthTree = authService.getAuthTreeByUserId(userId);
        return Result.ok(userAuthTree);
    }

    /**
     * 退出登录
     *
     * @param token
     * @return
     */
    @DeleteMapping("/logout")
    public Result logout(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token) {
        redisTemplate.delete(token);
        return Result.ok("退出成功");
    }
}
